package net.entelijan.cobean.bind.impl;

import net.entelijan.cobean.bind.IBeanProperty;
import net.entelijan.cobean.bind.IBinding;
import net.entelijan.cobean.bind.IModelChangeListener;
import net.entelijan.cobean.bind.IPropertyBindingStrategy;
import net.entelijan.cobean.bind.IRemovableFactory;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

class BoundPropertyBinding implements IBinding<Object> {

    private static Log log = LogFactory.getLog(BoundPropertyBinding.class);

    private static final long serialVersionUID = 1L;

    protected transient IPropertyBindingStrategy strat = new SpringPropertyBindingStrategy();
    private String modelProperty;
    protected String componentProperty;

    public BoundPropertyBinding() {
        super();
    }

    @Override
    public IModelChangeListener createModelChangeListener(IBeanProperty beanProperty, Object comp, IRemovableFactory removableFactory) {
        return new BoundPropertyBindingModelChangeListener(beanProperty, comp,
                this.componentProperty, this.strat, removableFactory);
    }

    @Override
    public <T> T bind(T model, Object view) {
        log.debug("[bind] modelProperty=" + modelProperty + " model=" + model + " viewProperty="
                + componentProperty + " view=" + view);
        if (this.componentProperty == null) {
            throw new IllegalArgumentException("[bind] this.viewProperty must not be null");
        }
        return this.strat.bind(model, this, view);
    }

    @Override
    public String toString() {
        return "BoundPropertyBinding [modelProperty=" + modelProperty + " viewProperty="
                + componentProperty + "]";
    }

    public void setStrat(IPropertyBindingStrategy strat) {
        this.strat = strat;
    }

    public IPropertyBindingStrategy getStrat() {
        return strat;
    }

    public String getComponentProperty() {
        return componentProperty;
    }

    public void setComponentProperty(String viewProperty) {
        this.componentProperty = viewProperty;
    }

    @Override
    public String getModelProperty() {
        return this.modelProperty;
    }

    public void setModelProperty(String modelProperty) {
        this.modelProperty = modelProperty;
    }

}
